package com.framework.persist;

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.framework.exception.FetchConnectionException;
import com.framework.util.ClassUtils;

public class DrvMgrDataSource implements DataSource {

	private static final Log logger = LogFactory.getLog(DrvMgrDataSource.class);

	private String driverClassName;

	private String url;

	private String username;

	private String password;

	private Properties connectionProperties;

	public DrvMgrDataSource() {

	}

	public DrvMgrDataSource(String driverClassName, String url,
			String username, String password) throws FetchConnectionException {
		setDriverClassName(driverClassName);
		setUrl(url);
		setUsername(username);
		setPassword(password);
	}

	public DrvMgrDataSource(String url, String username, String password)
			throws FetchConnectionException {
		setUrl(url);
		setUsername(username);
		setPassword(password);
	}

	public DrvMgrDataSource(String url) throws FetchConnectionException {
		setUrl(url);
	}

	public String getDriverClassName() {
		return driverClassName;
	}

	public void setDriverClassName(String driverClassName)
			throws FetchConnectionException {
		this.driverClassName = driverClassName.trim();
		try {
			Class.forName(this.driverClassName, true,
					ClassUtils.getDefaultClassLoader());
		} catch (ClassNotFoundException ex) {
			throw new FetchConnectionException(
					"Could not load JDBC driver class [" + this.driverClassName
							+ "]", ex);
		}
		if (logger.isInfoEnabled()) {
			logger.info("Loaded JDBC driver: " + this.driverClassName);
		}
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url.trim();
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public Properties getConnectionProperties() {
		return connectionProperties;
	}

	public void setConnectionProperties(Properties connectionProperties) {
		this.connectionProperties = connectionProperties;
	}

	public Connection getConnection() throws SQLException {

		return getConnectionFromDriverManager();
	}

	public Connection getConnection(String username, String password)
			throws SQLException {
		return getConnectionFromDriverManager(username, password);
	}

	protected Connection getConnectionFromDriverManager() throws SQLException {
		return getConnectionFromDriverManager(getUsername(), getPassword());
	}

	protected Connection getConnectionFromDriverManager(String username,
			String password) throws SQLException {
		Properties props = new Properties(getConnectionProperties());
		if (username != null) {
			props.setProperty("user", username);
		}
		if (password != null) {
			props.setProperty("password", password);
		}
		return getConnectionFromDriverManager(getUrl(), props);
	}

	protected Connection getConnectionFromDriverManager(String url,
			Properties props) throws SQLException {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating new JDBC Connection to [" + url + "]");
		}
		return DriverManager.getConnection(url, props);
	}

	public PrintWriter getLogWriter() throws SQLException {
		return null;
	}

	public void setLogWriter(PrintWriter out) throws SQLException {

	}

	public void setLoginTimeout(int seconds) throws SQLException {

	}

	public int getLoginTimeout() throws SQLException {
		return 0;
	}

	public <T> T unwrap(Class<T> iface) throws SQLException {
		return null;
	}

	public boolean isWrapperFor(Class<?> iface) throws SQLException {
		return false;
	}

}
